import random
import matplotlib
matplotlib.use('Agg')  # 使用非GUI后端
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak,Image
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.shapes import Drawing
from reportlab.lib.units import inch
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import A4
from datetime import date
import numpy as np
import matplotlib.pyplot as plt
from io import BytesIO


class toolPdf:
    def __init__(self, name, information):
        font_path = r"static\\fonts\\loadFont.ttf"  # 或使用其他中文字体文件
        pdfmetrics.registerFont(TTFont('loadFont', font_path))
        self.name = list()
        self.score = list()
        self.question = list()
        self.advice = list()

        self.id = name

        for item in information:
            self.name.append(item["name"])

            self.score.append(int(item["score"]))
            self.question.append(item["question"])
            self.advice.append(item["advice"])


        # 创建 PDF 文档
        self.doc = SimpleDocTemplate(
            rf"pdfResult\{self.id}.pdf",
            pagesize=A4,  # 设置页面尺寸
            leftMargin=72,    # 左边距（默认1英寸≈72pt）
            rightMargin=72,   # 右边距
            topMargin=72,     # 上边距
            bottomMargin=72   # 下边距
        )

        # 自定义字体
        self.styles = {
            'MainTitle': ParagraphStyle(
                name='MainTitle',
                fontName='loadFont',
                fontSize=32,
                alignment=1,
                spaceAfter=48
            ),
            "TinyBodyText": ParagraphStyle(
                name="TinyBodyText",
                fontName="loadFont",
                fontSize=12,
                leading=14,
                spaceAfter=28,
            ),
            'BodyText': ParagraphStyle(
                name='BodyText',
                fontName='loadFont',
                fontSize=21,
                leading=18,
                spaceAfter=28
            ),
            'MidBodyText': ParagraphStyle(
                name='BodyText',
                fontName='loadFont',
                fontSize=21,
                leading=14,
                alignment=1,
                spaceAfter=28
            ),
            'Heading1': ParagraphStyle(
                name='TableHeader',
                fontName='loadFont',
                fontSize=21,
                alignment=1,
                spaceAfter=28,

            ),
            'Heading2': ParagraphStyle(
                name='TableHeader',
                fontName='loadFont',
                fontSize=21,
                alignment=1,
                spaceAfter=28

            )
        }
        #元素
        self.elements = []

    def CreateTitle(self, text):
        title = Paragraph(text, self.styles["MainTitle"])
        self.elements.append(title)

    def CreateTinyBodyText(self, text):
        body_text = Paragraph(text, self.styles["TinyBodyText"])
        self.elements.append(body_text)
    def CreateBodyText(self, text):
        body_text = Paragraph(text, self.styles["BodyText"])
        self.elements.append(body_text)

    def CreateMidBodyText(self, text):
        body_text = Paragraph(text, self.styles["MidBodyText"])
        self.elements.append(body_text)
    def CreateTable(self, data):
        table_data = [[Paragraph(j, style=self.styles["BodyText"]) for j in i] for i in data]
        table = Table(table_data, colWidths=[1.5*inch]*len(table_data[0]))
        table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.lightblue),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTSIZE', (0, 0), (-1, 0), 12),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ]))
        self.elements.append(table)

    def CreateMatplotlibBarChart(self, column, data_groups, labels=None, colors=None,
                                 figsize=(10, 5), dpi=100, bar_width=0.35):

        # 配置中文字体
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False

        fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
        x = np.arange(len(column))  # 分类坐标
        total_groups = len(data_groups)

        # 设置默认颜色和标签
        colors = colors or plt.cm.tab10.colors[:total_groups]
        labels = labels or [f'数据组 {i + 1}' for i in range(total_groups)]

        # 绘制每组柱状图
        for i, (data, color, label) in enumerate(zip(data_groups, colors, labels)):
            offset = bar_width * i  # 计算偏移量
            rects = ax.bar(x + offset, data, bar_width,
                           color=color, label=label)
        # 设置图表样式
        ax.set_xticks(x + bar_width * (total_groups - 1) / 2)
        ax.set_xticklabels(column, rotation=45, ha='right')
        ax.set_ylim(0, 4.5)
        ax.set_ylabel('分数')
        ax.set_title('多维度对比分析')
        ax.legend(loc='upper right')

        # 调整布局并保存
        plt.tight_layout()
        buffer = BytesIO()
        plt.savefig(buffer, format='png', bbox_inches='tight')
        plt.close()

        # 创建Image对象（适当调整图片尺寸）
        buffer.seek(0)
        return Image(buffer, width=7 * inch, height=4 * inch)

    def ChangePage(self):
        self.elements.append(PageBreak())

    def HomePage(self):
        today = date.today()
        formatted_date = today.strftime("%Y:%m:%d")
        year = int(formatted_date[0:4])
        month = int(formatted_date[5:7])
        day = int(formatted_date[8:])

        for i in range(5):
            self.CreateTitle(text="")
        self.CreateTitle("小帕心理测评")
        self.CreateMidBodyText("根据PHQ-9")
        self.CreateMidBodyText(f"测试人：{self.id}")
        self.CreateMidBodyText(f"时间：{year}年{month}月{day}日")

    def OriginScorePage(self):

        current_data = [i/10 for i in self.score]
        # reference_data = [1.5, 1.5, 2.0, 2.5, 2.8, 1.8, 1.5, 1.5, 2.5, 1.8]

        # 添加标题
        self.CreateTitle("多维度对比分析")
        self.elements.append(Spacer(1, 0.5 * inch))

        # 生成并添加图表（传入两组数据）
        chart_img = self.CreateMatplotlibBarChart(
            column=self.name,
            data_groups=[current_data],
            labels=['当前测试'],
            colors=['#1f77b4']  # 蓝橙配色
        )
        self.elements.append(chart_img)

        # 添加说明文字
        self.elements.append(Spacer(1, 0.5 * inch))
        self.CreateTinyBodyText("注：蓝色表示当前测试分数")

    def PostscriptPage(self):
        self.CreateTitle("后 记：")
        self.CreateTinyBodyText("(1)、本报告书内容是依当事人的问卷回答产生的结果。其内容的真实性无法保证。而是需要与当事人进一步的沟通。")
        self.CreateTinyBodyText("(2)、本内容运用的领域是针对个人的行为、能力、价值及管理发展上，组织管理者不能视此报告作为唯一的评价依据，且本报告不负任何形式的法律问题。")
        self.CreateTinyBodyText("""
            本报告基于SCL-90测评结果，对测试者的心理健康状况进行了分析。结果显示，测试者在多个维度上均存在不同程度的心理问题，尤其是抑郁、焦虑和人际敏感等方面。这些问题可能显著影响生活质量、人际关系及日常功能。因此，采取适当的干预措施至关重要。
        """)

        self.CreateTinyBodyText("""
            建议测试者根据具体问题，积极实施相应的改善措施，如寻求专业心理咨询、参与社交技能培训及建立健康的生活方式。定期进行心理评估不仅能够监测心理健康状况的变化，还能帮助调整治疗方案，确保效果的持续性。
        """)

        self.CreateTinyBodyText("""
            我们强调，心理健康是整体健康的重要组成部分，定期进行心理评估能够帮助个体及时了解自身的心理状态，发现潜在问题，并采取必要的干预措施。建议测试者保持与心理咨询师的沟通，定期进行心理健康检查，以便获得更专业的指导和支持。
        """)

        self.CreateTinyBodyText("""
            心理咨询不仅可以帮助个体深入理解自身的情感和行为模式，还可以提供具体的应对策略和技巧，从而促进个人的心理成长和情感恢复。通过积极的自我照顾和专业支持，测试者有望实现心理健康的改善，提升生活质量。
        """)

        self.CreateTinyBodyText("""
            我们鼓励测试者对心理健康保持开放的态度，勇于寻求帮助，积极参与自我改善的过程。
        """)

        self.CreateTinyBodyText("""
            请务必重视心理健康，及时寻求专业帮助，以便获得所需的支持与指导，推动个人的全面发展与心理恢复。
        """)

    def AdvicePage(self):
        self.CreateTitle("建 议：")

        for _ in range(len(self.name)):

            self.CreateTinyBodyText(f"{_+1}.{self.name[_]}（{self.score[_]}）：")
            self.CreateTinyBodyText(f"问题:{self.question[_]}")
            advice = self.advice[_]
            if advice:
                self.CreateTinyBodyText("建议:")
                for ad in advice:
                    self.CreateTinyBodyText(ad)


    def run(self):
        #封面
        self.HomePage()
        self.ChangePage()

        #原始得分页
        self.OriginScorePage()
        self.ChangePage()

        #建议页
        self.AdvicePage()
        self.ChangePage()

        #总结页
        self.PostscriptPage()
        self.ChangePage()
        
        self.doc.build(self.elements)

#
# items = [
#     {
#         "id": 1,
#         "name": "躯体化",
#         "score": 21,
#         "question": "主观身体不适感较明显，可能导致生活质量下降。",
#         "advice": ["（1）身体检查：建议进行全面的身体检查，排除潜在的医疗问题。",
#                    "（2）放松训练：学习放松技巧，如深呼吸、渐进性肌肉放松或冥想，以缓解身体紧张和不适感。",
#                    "（3）健康生活方式：保持规律的锻炼和健康的饮食，增强身体抵抗力，减少身体不适。"]
#      },{
#         "id": 2,
#         "name": "强迫症状",
#         "score": 17,
#         "question": "存在强迫思维或行为，可能影响日常生活。",
#         "advice": ["（1）认知行为疗法（CBT）：建议参加CBT，帮助识别和改变强迫思维模式。",
#                    "（2）记录触发因素：建议保持日志，记录强迫症状的触发因素及其影响，帮助找到应对策略。",
#                    "（3）渐进暴露：逐步面对引发强迫行为的情境，帮助减少对这些情境的恐惧。"]
#      },{
#         "id": 3,
#         "name": "人际敏感",
#         "score": 25,
#         "question": "在社交场合感到不自在或自卑，可能影响人际关系。",
#         "advice": ["（1）社交技能训练：参加社交技能训练课程，提升自信心，学习更有效的沟通技巧。",
#                    "（2）小组活动：参与小组活动，逐步增加社交接触，以减少社交焦虑。",
#                    "（3）自我肯定练习：每日进行自我肯定练习，增强自我价值感和自信心。"]
#      },{
#         "id": 4,
#         "name": "抑郁症状",
#         "score": 39,
#         "question": "抑郁情绪明显，影响生活和学习。",
#         "advice": ["（1）寻求心理咨询：建议定期与心理咨询师会面，探索抑郁的根源，学习应对策略。"
#                    "（2）情绪记录：保持情绪日记，记录每日的情绪波动，识别触发抑郁情绪的事件。",
#                    "（3）自我照顾：注重自我照顾，如参与感兴趣的活动、保持良好的作息和饮食习惯。"]
#      },{
#         "id": 5,
#         "name": "焦虑症状",
#         "score": 33,
#         "question": "焦虑体验显著，影响生活质量",
#         "advice": ["（1）正念冥想：学习正念冥想或放松技巧，以降低焦虑水平。"
#                    "（2）识别焦虑源：分析并识别焦虑的根源，制定相应的应对策略。",
#                    "（3）社交支持：建立支持网络，与朋友和家人分享情感，获取情感支持。"]
#      },{
#         "id": 6,
#         "name": "敌对症状",
#         "score": 12,
#         "question": "存在轻微的敌对情绪，可能影响人际关系。",
#         "advice": ["（1）自我反思：鼓励进行自我反思，识别和理解敌对情绪的来源。"
#                    "（2）情绪管理技巧：学习情绪管理技巧，以应对和表达敌对情绪。",
#                    "（3）沟通技巧：加强沟通技巧，减少误解和冲突，增进人际关系的和谐。"]
#      },{
#         "id": 7,
#         "name": "恐怖症状",
#         "score": 12,
#         "question": "存在轻微的恐惧感，影响日常生活。",
#         "advice": ["（1）渐进式暴露：逐步面对恐惧情境，帮助减少对特定情境的恐惧"
#                    "（2）认知重构：学习识别和改变与恐惧相关的负面思维。",
#                    "（3）寻求专业帮助：如果恐惧感持续影响生活，建议寻求心理咨询。"]
#      },{
#         "id": 8,
#         "name": "偏执症状",
#         "score": 10,
#         "question": "存在轻微的猜疑和妄想，可能影响人际关系。",
#         "advice": ["（1）信任建设：练习信任他人的方法，通过逐步建立信任关系来减少偏执感。"
#                    "（2）认知行为技巧：学习CBT技巧，识别和挑战偏执的思维模式。",
#                    "（3）寻求心理支持：如果偏执感加剧，建议寻求专业心理支持。"]
#      },{
#         "id": 9,
#         "name": "饮食睡眠",
#         "score": 20,
#         "question": "饮食和睡眠问题需进一步检查，影响身心健康。",
#         "advice": ["（1）作息规律：建立规律的作息时间，确保充足的睡眠。"
#                    "（2）饮食均衡：关注饮食的营养均衡，尽量避免过度饮食或饮食不规律。",
#                    "（3）寻求专业意见：如有严重的饮食或睡眠问题，建议寻求营养师或睡眠专家的建议。"]
#      },{
#         "id": 10,
#         "name": "精神症状",
#         "score": 20,
#         "question": "可能存在轻微的精神症状，影响思维清晰度。",
#         "advice": ["（1）专业评估：与心理健康专业人士进行沟通，评估需要的支持和干预。"
#                    "（2）心理健康教育：学习关于精神健康的知识，帮助理解和应对可能的症状。",
#                    "（3）自我照顾：保持良好的生活习惯，如规律锻炼、健康饮食和充足的休息，以支持整体心理健康。"]
#      }
# ]
#
# tool = toolPdf(items)
# tool.main()

